package designpattern.singleton;

/**
 * 【这是最糟糕的实现方式】
 * 单例模式使用 volatile 修饰 的double check
 *
 *
 * 为什么使用volatile修饰 instance
 * 主要在于 instance = new Singleton()这句，并非是一个原子操作，事实上在JVM中这句话做了三件事情
 *      1)给instance分配内存
 *      2)调用Singleton的构造函数初始化成员变量
 *      3)将instance对象指向分配的内存空间(执行完这步 instance 就为非null了)
 *
 * 但是，在JVM的即时编译器中存在指令重排序优化
 * 也就是说，上面第二部和第三部顺序不能保证
 * 如果被执行顺序是1-3-2
 * 则在3执行完毕、2未执行之前，被线程二抢占了，这时instance已经是非null了，但没有初始化
 * 然后使用，报错
 *
 * 参考文档:
 * <a href="https://blog.csdn.net/goodlixueyong/article/details/51935526">Java单例模式--并非看起来那么简单</a>
 * <a href="https://coolshell.cn/articles/265.html">深入浅出单例Singleton设计模式</a>
 *
 * @Author Antony
 * @Since 2018/4/19 10:42
 */
public class Singleton {

    private volatile static Singleton instance = null;

    private Singleton(){}

    public static Singleton getInstance(){
        if(instance == null){
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
